package ocean.chinacraft.common.world.block.decoration;

import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.HorizontalBlock;
import net.minecraft.state.StateContainer;
import net.minecraft.util.Direction;
import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.IBooleanFunction;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.world.IBlockReader;

import javax.annotation.Nonnull;
import java.util.stream.Stream;

/**
 * 元宵灯笼
 *
 * @author zhang
 * @since 2021/12/8
 */
public class LanternFestivalLanterns extends HorizontalBlock {

    private final static VoxelShape SHAPES_N = Stream.of(
            Block.box(3, 2.5, 3, 13, 13.5, 13),
            Block.box(5.5, 0, 5.5, 10.5, 1, 10.5),
            Block.box(5.5, 15, 5.5, 10.5, 16, 10.5),
            Block.box(4.5, 1, 4.5, 11.5, 1.5, 11.5),
            Block.box(4.5, 14.5, 4.5, 11.5, 15, 11.5),
            Block.box(4, 1.5, 4, 12, 2, 12),
            Block.box(4, 14, 4, 12, 14.5, 12),
            Block.box(3.5, 2, 3.5, 12.5, 2.5, 12.5),
            Block.box(3.5, 13.5, 3.5, 12.5, 14, 12.5)
    ).reduce((v1, v2) -> VoxelShapes.join(v1, v2, IBooleanFunction.OR)).get();

    private final static VoxelShape SHAPES_W = Stream.of(
            Block.box(3, 2.5, 3, 13, 13.5, 13),
            Block.box(5.5, 0, 5.5, 10.5, 1, 10.5),
            Block.box(5.5, 15, 5.5, 10.5, 16, 10.5),
            Block.box(4.5, 1, 4.5, 11.5, 1.5, 11.5),
            Block.box(4.5, 14.5, 4.5, 11.5, 15, 11.5),
            Block.box(4, 1.5, 4, 12, 2, 12),
            Block.box(4, 14, 4, 12, 14.5, 12),
            Block.box(3.5, 2, 3.5, 12.5, 2.5, 12.5),
            Block.box(3.5, 13.5, 3.5, 12.5, 14, 12.5)
    ).reduce((v1, v2) -> VoxelShapes.join(v1, v2, IBooleanFunction.OR)).get();

    private final static VoxelShape SHAPES_S = Stream.of(
            Block.box(3, 2.5, 3, 13, 13.5, 13),
            Block.box(5.5, 0, 5.5, 10.5, 1, 10.5),
            Block.box(5.5, 15, 5.5, 10.5, 16, 10.5),
            Block.box(4.5, 1, 4.5, 11.5, 1.5, 11.5),
            Block.box(4.5, 14.5, 4.5, 11.5, 15, 11.5),
            Block.box(4, 1.5, 4, 12, 2, 12),
            Block.box(4, 14, 4, 12, 14.5, 12),
            Block.box(3.5, 2, 3.5, 12.5, 2.5, 12.5),
            Block.box(3.5, 13.5, 3.5, 12.5, 14, 12.5)
    ).reduce((v1, v2) -> VoxelShapes.join(v1, v2, IBooleanFunction.OR)).get();

    private final static VoxelShape SHAPES_E = Stream.of(
            Block.box(3, 2.5, 3, 13, 13.5, 13),
            Block.box(5.5, 0, 5.5, 10.5, 1, 10.5),
            Block.box(5.5, 15, 5.5, 10.5, 16, 10.5),
            Block.box(4.5, 1, 4.5, 11.5, 1.5, 11.5),
            Block.box(4.5, 14.5, 4.5, 11.5, 15, 11.5),
            Block.box(4, 1.5, 4, 12, 2, 12),
            Block.box(4, 14, 4, 12, 14.5, 12),
            Block.box(3.5, 2, 3.5, 12.5, 2.5, 12.5),
            Block.box(3.5, 13.5, 3.5, 12.5, 14, 12.5)
    ).reduce((v1, v2) -> VoxelShapes.join(v1, v2, IBooleanFunction.OR)).get();

    public LanternFestivalLanterns() {
        super(Properties.copy(Blocks.LANTERN));
    }

    @Override
    public VoxelShape getShape(BlockState state, IBlockReader reader, BlockPos pos, ISelectionContext context) {
        Direction direction = state.getValue(FACING);
        switch (direction) {
            case NORTH:
                return SHAPES_N;
            case SOUTH:
                return SHAPES_S;
            case EAST:
                return SHAPES_E;
            case WEST:
                return SHAPES_W;
            default:
                return SHAPES_N;
        }
    }


    @Override
    public BlockState rotate(BlockState blockState, Rotation rotation) {
        return blockState.setValue(FACING, rotation.rotate(blockState.getValue(FACING)));
    }

    @Override
    public BlockState mirror(BlockState state, Mirror mirror) {
        return state.rotate(mirror.getRotation(state.getValue(FACING)));
    }

    @Override
    protected void createBlockStateDefinition(@Nonnull StateContainer.Builder<Block, BlockState> builder) {
        builder.add(FACING);
    }
}
